import axios from 'axios'
// 导入store
import store from '@/store'
// 导入router
import router from '@/router'
// 导入toast
import { Toast } from 'vant'

const baseURL = 'http://toutiao.itheima.net'
// 有可能有多个接口服务器的，但是也不决不是像现在这样用

// 克隆一个新的对象并设置基地质
const request = axios.create({
    // 注意：复制的时候如果有空格，记得一定要把空格去掉！记得一定要把空格去掉！记得一定要把空格去掉！
    baseURL
})

// 请求拦截器 - 只要是通过request发的请求，那么都会拦截下来
request.interceptors.request.use(config => {
    // config就是本次请求的相关信息
    // console.log('config', config)
    // 那如果config里有token？
    // 比如说我做登录时，需要携带token吗？不需要
    // 而且那时候也没有token，所以要做判断
    // 有token才加请求头，没token就不加
    if (store.state.tokenObj.token) {
        config.headers.Authorization = 'Bearer ' + store.state.tokenObj.token
    }
    // 这里return config就是也有token
    // 就意味着请求里也携带了token
    return config

}, err => {

    return Promise.reject(err)
})

// 拦截应该request -- 响应拦截
request.interceptors.response.use(response => {

    return response.data

}, async err => {
    // 先判断是不是401错误
    if (err.response.status == 401) {

        try {
        // 就代表token有问题，就利用refresh_token去刷新得到一个最新的token
        // request这个对象是有请求拦截的，所以如果你用request发请求，明明给的是refresh_token
        // 但是他会自动替换成token，所以服务器报错
        // 所以axios这个对象发请求就没问题了，因为他没有请求拦截，你发什么，服务器拿到的就是什么
        // 只不过axios没有设置基地址，所以地址要写完整
        const res = await axios({
            url: `${baseURL}/v1_0/authorizations`,
            method: 'put',
            headers: {
                Authorization: 'Bearer ' + store.state.tokenObj.refresh_token
            }
        })

        // 拿到新token后把vuex里的token替换成最新token
        store.commit('changeToken', {
            token: res.data.data.token,
            refresh_token: store.state.tokenObj.refresh_token
        })

        // 代码来到这就意味着有新的token了
        // 有新的token就要把原本失败的请求再利用
        // 新的token再发一次，问题来了：原本发的请求信息存在那里面了？
        // 这里不用把请求发token改成获取到的新token吗？
        // 不用！因为这里特意用request这个对象发的请求
        // 那就会触发他的请求拦截，请求拦截里会自动用最新的token覆盖
        return request(err.config)
    }catch {

        // 能来到catch，只能证明连refresh_token都过期了
        // 打回登录页，让用户重新登录
        Toast('登录状态已失效，请重新登录！')
        router.push('/login')
        // 随便给它return一个数据即可
        return ''
    }

    }else {
        // 直接抛出Promise.reject就会报错
        // Promise.reject就是抛出一个错误
        return Promise.reject(err)
    }
})


export default request